local ActivityExcel = require("excel.Activity")
local ActRuleConfig = ActivityExcel.dailyActRule
local Map = require("core.Map")
local InnerDataManagerFW = require("innerdata.InnerDataManagerFW")
local InnerDataDefine = require("innerdata.Define")
local DailyActFW = require("activity.DailyActFW")
local ActDefine = require("activity.Define")
local Util = require("common.Util")
local MailLogicFW = require("mail.MailLogicFW")
local Lang = require("common.Lang")
local Grid = require("bag.Grid")
local ItemDefine = require("bag.ItemDefine")
local Broadcast = require("broadcast.Broadcast")
local LuaMongo = _G.lua_mongo
local DB = require("common.DB")
local MapExcel = require("excel.Map")
local ExcelMonster = require("excel.Monster")

--function onBeginBefore(actNum, actArgs)
--    print("world boss has beginbefore")
--end

WorldBossList = WorldBossList or {}

function onRunning(actNum, actArgs)
    print("world boss has running")
    local nRulID = actArgs.ruleid
    local nActRule = ActRuleConfig[nRulID]
    if nActRule then
        local nArgData = nActRule.args
        local nCopyID = nArgData[ActDefine.ACT_ARGS_MONSTER_COPYID]
        local nMonsterPosX = nArgData[ActDefine.ACT_ARGS_MONSTER_POSX]
        local nMonsterPosY = nArgData[ActDefine.ACT_ARGS_MONSTER_POSY]
        local nMonsterID = nArgData[ActDefine.ACT_ARGS_MONSTERID]
        local nMapID = MapExcel.copy[nCopyID].mapList[1]

        --local noKillDay = 0
        --local nBossLv = 0

        --local lvDownData = ExcelMonster.monster[nMonsterID].dynamic_lvdown

        --if WorldBossList[actArgs._configID] then
        --    --这里加3600 一小时是为了避免误差的问题，增加几分钟也可
        --    local noKillDay = math.floor(WorldBossList[actArgs._configID].lastKillTime and math.abs((os.time() - ((WorldBossList[actArgs._configID].lastKillTime or 0) + 3600))) / 86400)
        --    local noKillDayLv = math.floor(noKillDay / lvDownData)
        --    local nSrcLv = WorldBossList[actArgs._configID].lv or 0
        --    nBossLv = nSrcLv

        --    nDecLv = (nSrcLv - noKillDayLv) < 0 and 0 or (nSrcLv - noKillDayLv)
        --    if nDecLv ~= nSrcLv then
        --        WorldBossList[actArgs._configID].killCount = 0
        --        WorldBossList[actArgs._configID].lastKillTime = os.time()
        --        WorldBossList[actArgs._configID].lv = nDecLv 
        --        nBossLv = nDecLv
        --        saveDB(actArgs._configID, nil, nMonsterID)
        --    end
        --end

        local nSend2Ldata = {
            type = 1,
            data = {
                monsterID = nMonsterID,
                posX = nMonsterPosX,
                posY = nMonsterPosY,
                mapID = nMapID,
                copyID = nCopyID,
                lasttime = DailyActFW.onGetLeftTime(actNum, actArgs),
                endtime = DailyActFW.onGetEndTime(actNum, actArgs),
                --lv = nBossLv,
            }
        }

        InnerDataManagerFW.Send2LInnerData(nil, InnerDataDefine.INNERDATA_TYPE_WORLDBOSS, nSend2Ldata)
        local nMonsterName = ExcelMonster.monster[nMonsterID].name
        local nMapName = MapExcel.scene[nMapID].name
        local nStr = string.format(Lang.DAILY_ACTIVITY_WORLDBOSS_OPEN, nMonsterName, nMapName, actNum)
        Broadcast.sendBroadcast2World(Lang.GROSSIP + Lang.UP, nStr)
    end
end

function onEnd(actNum, actArgs)
    print("world boss has end")
    local nRulID = actArgs.ruleid
    local nActRule = ActRuleConfig[nRulID]
    if nActRule then
        local nArgData = nActRule.args
        local nCopyID = nArgData[ActDefine.ACT_ARGS_MONSTER_COPYID]
        local nMapID = MapExcel.copy[nCopyID].mapList[1]

        local nSend2Ldata = {
            type = 2,
            data = {
                mapID = nMapID,
            }
        }

        local logicID = Map.get_logic_id(nMapID)
        InnerDataManagerFW.Send2LInnerData(nil, InnerDataDefine.INNERDATA_TYPE_WORLDBOSS, nSend2Ldata, logicID)
    end
end

local function get_grid(itemID, itemNum, itemColor, itemBind)
    local grid = Grid.create(nil, itemID, itemNum, itemBind, ItemDefine.qualityOut[itemColor])
    return grid
end

function onBossDie(data)
    local nHurtRankData = data.rankData
    local actArgs = data.actArgs
    local nResult = data.result
    --注意，这里的actArgs并不是W线程中活动框架内存的，而是由L线程发上来的，如果要实时数据，应该重新在W线程中取出活动参数

    if not nHurtRankData or not actArgs then
        return
    end

    local nActRule = ActRuleConfig[actArgs.ruleid]
    if nActRule then
        local nRewardConfigData = nil 
        local nMailContent = ""
        if nResult == 0 then
            nRewardConfigData = nActRule.item[3]
            nMailContent = "亲，恭喜您在世界BOSS挑战中伤害排名第%d名"
        elseif nResult == 1 then
            nRewardConfigData = nActRule.item[5]
            nMailContent = "亲，虽然BOSS逃跑了，但恭喜您在世界BOSS挑战中伤害排名第%d名"
        end

        if nRewardConfigData then
            for k, v in ipairs(nHurtRankData) do
                if k > 10 then
                    break
                end
                local nRewardData = nil
                local nRewardList = {}
                if k <= 3 then
                    nRewardData = nRewardConfigData[k]
                else
                    nRewardData = nRewardConfigData[4]
                end
                if nRewardData then
                    nRewardList[#nRewardList + 1] = get_grid(nRewardData[1], nRewardData[2], nRewardData[3], nRewardData[4] or 0)
                end
                MailLogicFW.addSystemMessage(v[3], "世界BOSS伤害排名奖励", string.format(nMailContent, k), nRewardList)
            end
        end

        local nLastHit = data.lastHit
        if nLastHit then
            local nArgData = nActRule.args
            local nMonsterID = nArgData[ActDefine.ACT_ARGS_MONSTERID]
            local nRewardData = nil
            local nRewardList = {}
            nRewardData = nActRule.item[4][1]
            if nRewardData then
                nRewardList[#nRewardList + 1] = get_grid(nRewardData[1], nRewardData[2], nRewardData[3], nRewardData[4] or 0)
            end

            MailLogicFW.addSystemMessage(nLastHit[2], "世界BOSS最后击杀奖励", "亲,恭喜您在世界BOSS挑战中造成致命性一击", nRewardList)
            local nMonsterName = ExcelMonster.monster[nMonsterID].name
            local nStr = string.format(Lang.DAILY_ACTIVITY_WORLDBOSS_LASTHIT, nLastHit[1], nMonsterName)
            Broadcast.sendBroadcast2World(Lang.GROSSIP + Lang.UP, nStr)
            saveDB(actArgs._configID, nLastHit, nMonsterID)
        end
        DailyActFW.onSetActFinish(actArgs.type, actArgs)
    end
end

function saveDB(actConfigID, lastHit, monsterID)
    --local nKillCount = WorldBossList[actConfigID] and WorldBossList[actConfigID].killCount or 0
    --local nLv = WorldBossList[actConfigID] and WorldBossList[actConfigID].lv or 0
    --WorldBossList[actConfigID] = nil

    if WorldBossList[actConfigID] then
        WorldBossList[actConfigID].lastHitName = lastHit[1]
        WorldBossList[actConfigID].lastHitUuid = lastHit[2]
        WorldBossList[actConfigID].lastKillTime = os.time()
    else
        WorldBossList[actConfigID] = {actConfigID = actConfigID, lastHitUuid = lastHit[2], lastHitName = lastHit[1], lastKillTime = 0}
    end
    LuaMongo.update(DB.db_worldboss, {actConfigID = actConfigID}, WorldBossList[actConfigID], true)
end

function onGetLastHitUser(actConfigID)
    --LuaMongo.find(DB.db_worldboss, {actConfigID = actConfigID})
    --local nLastHitData = nil
    --local nReader = {}
    --if not LuaMongo.next(nReader) then
    --    return
    --end
    --nLastHitData = {}
    --nLastHitData.lastHitUuid = nReader.lastHitUuid
    --nLastHitData.lastHitName = nReader.lastHitName
    --return nLastHitData
    if WorldBossList[actConfigID] then
        nLastHitData = {}
        nLastHitData.lastHitUuid = WorldBossList[actConfigID].lastHitUuid
        nLastHitData.lastHitName = WorldBossList[actConfigID].lastHitName
        return nLastHitData
    end
end

function onInit()
    LuaMongo.find(DB.db_worldboss)
    while true do
        local nReader = {}
        if not LuaMongo.next(nReader) then
            break
        end

        WorldBossList[nReader.actConfigID] = {actConfigID = nReader.actConfigID, lastHitUuid = nReader.lastHitUuid, lastHitName = nReader.lastHitName, lastKillTime = nReader.lastKillTime}
    end
end

onInit()

DailyActFW.onRegisterCallBack(ActDefine.ACT_TYPE_WORLDBOSS, onBeginBefore, onRunning, onEnd, nil)
